#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>


//编译时 要是用 -pthread 选项
//gcc 10-pthread.c -o 10-pthread -pthread
#define N 128
char buf[N+1]={0};
pthread_mutex_t mutex_w1,mutex_w2,mutex_r1,mutex_r2;


void * pthread_handler1(void *arg)
{
    printf("arg1=%d\n",*(int *)arg);
    printf("1: pthread_handler is running\n");
    while(1)
    {
        pthread_mutex_lock(&mutex_w1);// P操作 
        memset(buf,'O',64);
        usleep(1000);//延迟1000us
        memset(buf+64,'O',64);//保证最后一个元素是0
        usleep(1000);//延迟1000us
        pthread_mutex_unlock(&mutex_r1);//V操作 
    }
}

void * pthread_handler2(void *arg)
{
    printf("arg2=%d\n",*(int *)arg);
    printf("2: pthread_handler is running\n");
    while(1)
    {
        pthread_mutex_lock(&mutex_w2);// P操作 
        memset(buf,'-',64);
        usleep(1000);//延迟1000us
        memset(buf+64,'-',64);//保证最后一个元素是0
        usleep(1000);//延迟1000us
        pthread_mutex_unlock(&mutex_r2);// V操作 
    }
}

void * pthread_handler3(void *arg)
{
    printf("arg3=%d\n",*(int *)arg);
    printf("3: pthread_handler is running\n");
    while(1)
    {
        pthread_mutex_lock(&mutex_r1);// P操作 
        printf("buf=%s\n",buf);
        sleep(1);
        pthread_mutex_unlock(&mutex_w2);// V操作 

    }
}

int main(int argc, char const *argv[])
{    
    pthread_t tid1,tid2,tid3;//pthread id 线程 id
    int data1=100,data2=200,data3=300;

    int ret;
    
    // 锁被初始化后, 锁的状态是开的
    // pthread_lock 加锁后, 锁的状态是关闭状态
    // pthread_unlock 解锁后, 锁的状态是开的状态
    ret = pthread_mutex_init(&mutex_w1,NULL);
    if (ret != 0)
    {
        printf("pthread_mutex_init error\n");
        exit(-1);
    }
    ret = pthread_mutex_init(&mutex_w2,NULL);
    if (ret != 0)
    {
        printf("pthread_mutex_init error\n");
        exit(-1);
    }
    ret = pthread_mutex_init(&mutex_r1,NULL);
    if (ret != 0)
    {
        printf("pthread_mutex_init error\n");
        exit(-1);
    }
    ret = pthread_mutex_init(&mutex_r2,NULL);
    if (ret != 0)
    {
        printf("pthread_mutex_init error\n");
        exit(-1);
    }
    pthread_mutex_lock(&mutex_w2);
    pthread_mutex_lock(&mutex_r1);
    pthread_mutex_lock(&mutex_r2);
    //创建子线程1
    ret = pthread_create(&tid1,NULL,pthread_handler1,(void *)&data1);
    if (ret !=0)
    {
        printf("1: pthread_create eror\n");
    }

    //创建子线程2
    ret = pthread_create(&tid2,NULL,pthread_handler2,(void *)&data2);
    if (ret !=0)
    {
        printf("2: pthread_create eror\n");
    }

    //创建子线程3
    ret = pthread_create(&tid3,NULL,pthread_handler3,(void *)&data3);
    if (ret !=0)
    {
        printf("3: pthread_create eror\n");
    }

    printf("tid1=%ld\n",tid1);
    printf("tid2=%ld\n",tid2);
    printf("tid3=%ld\n",tid3);

    while (1)
    {
        pthread_mutex_lock(&mutex_r2); // P操作
        printf("buf=%s\n", buf);
        sleep(1);
        pthread_mutex_unlock(&mutex_w1); // V操作
    }

    return 0;
}
